#!/usr/bin/perl
#find_serv.cgi

use Socket;

require './mdmsearch-lib.pl';
&ReadParse();

my @servers = sort { $a->{'id'} cmp $b->{'id'} } &list_servers;
foreach $s (@servers) {
	$server{$s->{'id'}}++;
	$servip{$s->{'ip'}}++;
}
local $mysysid=&get_systemid();
$myserv{$mysysid}++;
my $port = $config{'listen'} ? $config{'listen'}:10000;
socket(BROAD, PF_INET, SOCK_DGRAM, getprotobyname("udp")) || &error("socket failed: $!");

&header($text{'find_title'}, "");

if ($in{'findtype'} eq 'S'){
	if ($in{'register'} eq 'write'){
		print "<form name=regserv action=find_serv.cgi method=post>\n";
		print "<input type=hidden name=findtype value='S'>\n";
		print "<input type=hidden name=register value='search'>\n";
		print "<table class=mode1 border=0 cellpadding=5 cellspacing=0>\n";
		print "<tr><td><b>$text{'ip'}:</b></td><td><input name=regip></td>\n";
		print "<td>&nbsp&nbsp&nbsp<input type=submit class=button1 value='$text{'register'}'></td></tr></table>\n";
		print "</form>\n";		
	}else{
		if ($in{'regip'} eq ""){
			&error($text{'err_noip'});
		}elsif(($in{'regip'}=~ /^\D/)){
			&error($text{'err_wrongip'});
		}elsif(!&check_ipaddress($in{'regip'})){
			&error($text{'err_wrongip'});
		}elsif($servip{$in{'regip'}}){
			&error($text{'err_dubreg'});
		}
		
		send(BROAD, "ezstor-server", 0, sockaddr_in($port, inet_aton($in{'regip'})));
	}

}elsif($in{'findtype'} eq 'M'){
	setsockopt (BROAD, 0, 33,pack('I', 31)) || &error("setsockopt failed: $!");
	
	foreach $s (@servers){
		&set_status_unrun($s->{'id'});
		push (@broad,$s->{'ip'});
	}
	push(@broad, "230.230.230.230");

	foreach $toip (@broad){
		send(BROAD, "ezstor-server", 0, sockaddr_in($port, inet_aton($toip)));
	}

}elsif($in{'findtype'} eq 'B'){
	setsockopt(BROAD, SOL_SOCKET, SO_BROADCAST, pack("l", 1)) || &error("setsockopt failed: $!");
	foreach $s (@servers){
		&set_status_unrun($s->{'id'});
		push (@broad,$s->{'ip'});
	}
	push(@broad, "255.255.255.255");

	foreach $toip (@broad){
		send(BROAD, "ezstor-server", 0, sockaddr_in($port, inet_aton($toip)));
	}
	
}else{
	&error("Page Failed! Try again!");
}


# Get and display responses
$| = 1;
if (($in{'findtype'} eq 'S') && ($in{'register'} eq 'search')){
	local $rcv;
	vec($rcv,fileno(BROAD),1)=1;
	local $logoper = "Register a new device";
	if (select($rcv,undef,undef,1)){
		local $buf;
		local $from=recv(BROAD,$buf,1024,0);
		
		if (!$from){
			local @data;
			$data[0]="can't find this device.";
			&foreign_call("mdmhistory","mdm_log",$logoper,\@data);
			&error ($text{'err_notregister'});
		}else{
			local ($fromport, $fromaddr) = sockaddr_in($from);
			local $fromip = inet_ntoa($fromaddr);
		
			if ($fromip ne $in{'regip'}){
				local @data;
				$data[0]="can't find this device.";
				&foreign_call("mdmhistory","mdm_log",$logoper,\@data);
				&error($text{'err_notregister'});
			}
	
			local ($systemid,$hostname) = split(/:/, $buf);
			local $url = "https://$fromip:10000/";			
			if($systemid eq $mysysid){
				print &text('find_me',"<tt>$url</tt>"),"<br>\n";
			}else{
				print &text('find_reg',"<tt>$url</tt>"),"<br>\n";
				if ($server{$systemid}){
					local @data;
					$data[0]="find an old device,systemid $systemid,IP $fromip";
					&foreign_call("mdmhistory","mdm_log",$logoper,\@data);
					&save_old_serv($systemid,$hostname,$fromip,"##","##");
				}else{
					local @data;
					$data[0]="find a new device,systemid $systemid,IP $fromip";
					&foreign_call("mdmhistory","mdm_log",$logoper,\@data);			
					&save_new_serv($systemid,$hostname,$fromip,"","");
				}
			}
		}
	}else{
		local @data;
		$data[0]="can't find this device with the ip $in{'regip'}";
		&foreign_call("mdmhistory","mdm_log",$logoper,\@data);
		&error(&text('err_notregister'));
	}
}elsif(($in{'findtype'} ne 'S')){
	$limit = $config{'scan_time'} ? $config{'scan_time'}:2 ;
	$tmstart = time();
	local $logoper;
	if (($in{'findtype'} eq 'M')){
		$logoper = "Search in all LANs";
	}else{
		$logoper = "Search in local LAN";
	}
	local @data;
	while ((time()-$tmstart) < $limit) {
		local $rcv;
		vec($rcv,fileno(BROAD),1)=1;
		if (select($rcv,undef,undef,1)){
			local $buf;
			local $from=recv(BROAD,$buf,1024,0);
			next if (!$from);
			local ($fromport,$fromaddr)= sockaddr_in($from);
			local $fromip=inet_ntoa($fromaddr);
			if($fromip !~ /\.(255|0)$/ && !($already{$fromip}++)){
				local ($systemid,$hostname) = split(/:/, $buf);
				local $url = "https://$fromip:10000/";
				if ($server{$systemid}){
					print &text('find_already',"<tt>$url</tt>"),"<br>\n";
					push @data,"find an exit device,systemid $systemid,IP $fromip";
					&save_old_serv($systemid,$hostname,$fromip,"##","##");
				}elsif($myserv{$systemid}){
					print &text('find_me',"<tt>$url</tt>"),"<br>\n";
				}else{
					print &text('find_new',"<tt>$url</tt>"),"<br>\n";
					push @data,"find a new device,systemid $systemid,IP $fromip";
					&save_new_serv($systemid,$hostname,$fromip,"","");					
				}										
			}
			
		}
	}
	&foreign_call("mdmhistory","mdm_log",$logoper,\@data);	
}

&footer('index.cgi',"$text{'index_title'}");
1;
